package com.example.demo3.util;

import com.example.demo3.annotation.Crypt;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.Arrays;

/**
 * @author allnas
 */
@Slf4j
public class CryptService {

    @Resource
    private AesUtils aesUtils;

    @Resource
    private SM4Utils sm4Utils;

    @SneakyThrows
    public void encrypt(Object object) {
        Class<?> clazz = object.getClass();
        //获取属性注解
        Field[] fields = clazz.getDeclaredFields();
        Arrays.stream(fields).filter(field -> field.isAnnotationPresent(Crypt.class)).forEach(field -> {
            //打开私有访问
            field.setAccessible(true);
            Crypt crypt = field.getAnnotation(Crypt.class);
            try {
                Object value = field.get(object);
                switch (crypt.algorithm()) {
                    case AES:
                        field.set(object, aesUtils.encrypt(value.toString()));
                        break;
                    case SM4:
                        field.set(object, sm4Utils.encrypt(value.toString()));
                        break;
                    default:
                        field.set(object, aesUtils.encrypt(value.toString()));
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    @SneakyThrows
    public void decrypt(Object object) {
        Class<?> clazz = object.getClass();
        //获取属性注解
        Field[] fields = clazz.getDeclaredFields();
        Arrays.stream(fields).filter(field -> field.isAnnotationPresent(Crypt.class)).forEach(field -> {
            //打开私有访问
            field.setAccessible(true);
            Crypt crypt = field.getAnnotation(Crypt.class);
            try {
                Object value = field.get(object);
                switch (crypt.algorithm()) {
                    case AES:
                        field.set(object, aesUtils.decrypt(value.toString()));
                        break;
                    case SM4:
                        field.set(object, sm4Utils.decrypt(value.toString()));
                        break;
                    default:
                        field.set(object, aesUtils.decrypt(value.toString()));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
}
